/*
 * DAO voor het opzoeken van voorstellingen,
 * het lezen van een bepaalde voorstelling
 * en het reserveren van een bepaalde voorstelling.
 */
package be.vdab.dao;
import be.vdab.entiteit.Klant;
import be.vdab.entiteit.Reservatie;
import be.vdab.entiteit.Voorstellingen;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 *
 * @author tom.vanpoucke
 */
public class VoorstellingDAO extends AbstractDAO{
    private static final String FIND_GENRES = 
            "select * from genres";
    private static final String FIND_VOORSTELLINGEN = 
            "select * from genres inner join voorstellingen on genres.genreNr = voorstellingen.genreNr where genre = ? order by datum";
    private static final String READ_VOORSTELLING=
            "select * from voorstellingen where voorstellingsNr = ?";
    private static final String NIEUWE_RESERVATIE= 
            "insert into reservaties(klantnr, voorstellingsnr, plaatsen) values(?,?,?)";
    private static final String UPDATE_VRIJEPLAATSEN=
            "update voorstellingen set voorstellingen.VrijePlaatsen = (voorstellingen.VrijePlaatsen - ?) where voorstellingsNr = ? and voorstellingen.VrijePlaatsen-? >= 0";
    
    public List<String> findGenres(){
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        try{
            List<String> genres = new ArrayList<String>();
            connection = getConnection();
            statement = connection.createStatement();
            resultSet = statement.executeQuery(FIND_GENRES);
            while(resultSet.next()){
                genres.add(resultSet.getString("genre"));
            }
            return genres;
        }
        catch(SQLException ex){
            throw new DAOException("Kan genres niet lezen uit database", ex);
        }
        finally{
            close(resultSet, statement, connection);
        }      
    }   
    public List<Voorstellingen> findVoorstelling(String genre){
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        Date date = new Date();
        try{
            List<Voorstellingen> voorstellingen = new ArrayList<Voorstellingen>();
            connection = getConnection();
            statement = connection.prepareStatement(FIND_VOORSTELLINGEN);
            statement.setString(1, genre);
            resultSet = statement.executeQuery();
            while (resultSet.next()){
                if(resultSet.getDate("Datum").after(date)){
                    voorstellingen.add(resultSetRijNaarVoorstelling(resultSet));
                }
            }
            return voorstellingen;
        }
        catch(SQLException ex){
            throw new DAOException("Kan voorstellingen niet lezen uit database", ex);
        }
        finally{
            close(resultSet, statement, connection);
        }
    }   
    public Voorstellingen read(int nummer){
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        Voorstellingen voorstelling = null;
        try{
            connection = getConnection();
            statement = connection.prepareStatement(READ_VOORSTELLING);
            statement.setString(1, Integer.toString(nummer) );
            resultSet = statement.executeQuery();
            while(resultSet.next()){
                voorstelling = resultSetRijNaarVoorstelling(resultSet);
            }
            return voorstelling;
        }
        catch(SQLException ex){
            throw new DAOException("kan voorstelling niet lezen uit database", ex);
        }
        finally{
            close(resultSet, statement, connection);
        }
    }  
    public void reserveren(Reservatie reservatie, Klant klant) throws SQLException{
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        try{
            connection = getConnection();
            connection.setAutoCommit(false);
            
            statement = connection.prepareStatement(NIEUWE_RESERVATIE);
            statement.setInt(1, klant.getKlantNr());
            statement.setInt(2, reservatie.getVoorstelling().getVoorstellingsNr());
            statement.setInt(3, reservatie.getPlaatsen());
            int res1 = statement.executeUpdate();
            
            statement = connection.prepareStatement(UPDATE_VRIJEPLAATSEN);
            statement.setInt(1, reservatie.getPlaatsen());
            statement.setInt(2, reservatie.getVoorstelling().getVoorstellingsNr());
            statement.setInt(3, reservatie.getPlaatsen());
            int res2 = statement.executeUpdate();
            
            if(res1 == 0 || res2 == 0){
                throw new SQLException();
            }
            else{
                connection.commit();
            }           
        }
        catch(SQLException ex){
            if(connection != null){
                try{
                connection.rollback();
                }
                catch(SQLException ex2){
                    throw new DAOException("Fout tijdens rollback", ex2);
                }
                throw new SQLException();
            }
            else{
                throw new DAOException("Fout met de database", ex);
            }
        }
        finally{
            close(resultSet, statement, connection);
        }
    }    
    private Voorstellingen resultSetRijNaarVoorstelling(ResultSet resultSet) throws SQLException{
        return new Voorstellingen(resultSet.getInt("VoorstellingsNr"),
                resultSet.getString("Titel"),
                resultSet.getString("uitvoerders"),
                resultSet.getTimestamp("Datum"),
                resultSet.getDouble("Prijs"),
                resultSet.getInt("VrijePlaatsen"));
    }
}